package com.travelsky.login.service;

import com.travelsky.login.domain.Account;
import com.travelsky.login.domain.AccountRepository;
import com.travelsky.login.domain.AuthenticateFailedException;
import com.travelsky.login.domain.User;
import com.travelsky.login.domain.UserRepository;
import java.util.List;
import java.util.Objects;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
class LoginServiceImpl implements LoginService {

  private final AccountRepository accountRepository;
  private final UserRepository userRepository;
  private final List<AccountVerifier> accountVerifiers;

  @Autowired
  public LoginServiceImpl(AccountRepository accountRepository,
      UserRepository userRepository,
      List<AccountVerifier> accountVerifiers) {
    this.accountRepository = accountRepository;
    this.userRepository = userRepository;
    this.accountVerifiers = accountVerifiers;
  }

  /**
   * 登录
   *
   * @param userId 用户名
   * @param password 密码
   * @return 用户信息
   */
  @Override
  public User login(String userId, String password) {
    // 通过用户名查询账户信息
    Account account = getAccountBy(userId);
    // 账户认证
    authenticateAccount(password, account);
    // 校验账户信息
    validateAccount(account);
    // 查询用户信息
    return getUserBy(userId);
  }

  private void validateAccount(Account account) {
    accountVerifiers.forEach(accountVerifier -> accountVerifier.verify(account));
  }

  private void authenticateAccount(String inputPassword, Account account) {
    // 校验账户是否存在
    checkAccountExist(account);
    // 校验密码
    checkPasswordCorrectly(account.getPassword(), inputPassword);
  }

  private User getUserBy(String userId) {
    return userRepository.findBy(userId);
  }

  private Account getAccountBy(String userId) {
    return accountRepository.findBy(userId);
  }

  private void checkAccountExist(Account account) {
    if (Objects.isNull(account)) {
      throw new AuthenticateFailedException("00001", "用户名或密码错误!");
    }
  }

  private void checkPasswordCorrectly(String password, String inputPassword) {
    if (isPasswordEquals(password, inputPassword)) {
      return;
    }
    throw new AuthenticateFailedException("00001", "用户名或密码错误!");
  }

  private boolean isPasswordEquals(String password, String inputPassword) {
    return password.equals(inputPassword);
  }
}
